package com.rem.concurrency.juc.my1Base;


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Lock安全卖票
 * <p>
 * <p>
 * Synchronized 和 Lock 区别
 * 1、Synchronized 内置的Java关键字， Lock 是一个Java类
 * 2、Synchronized 无法判断获取锁的状态，Lock 可以判断是否获取到了锁
 * 3、Synchronized 会自动释放锁，lock 必须要手动释放锁！如果不释放锁，死锁
 * 4、Synchronized 线程 1（获得锁，阻塞）、线程2（等待，傻傻的等）；Lock锁就不一定会等待下
 * 去；
 * 5、Synchronized 可重入锁，不可以中断的，非公平；Lock ，可重入锁，可以 判断锁，非公平（可以
 * 自己设置）；
 * 6、Synchronized 适合锁少量的代码同步问题，Lock 适合锁大量的同步代码！
 *
 * @author Rem
 * @date 2021-03-08
 */

public class LockSale {

    public static void main(String[] args) {
        Ticket3 ticket = new Ticket3();

        /**
         * 多线程操作同一资源 对于资源来说没有附属条件
         */
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        }, "C").start();
    }
}


/**
 * 资源类
 */
class Ticket3 {
    private Integer num = 30;
    private Lock lock = new ReentrantLock();

    void sale() {
        lock.lock();
        try {
            if (num > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了" + num-- + "--->剩余张数" + num);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
